package xyz.scootaloo.kami.cloud.model.core

import io.vertx.core.json.JsonObject
import xyz.scootaloo.kami.cloud.lang.JsonSerializable
import xyz.scootaloo.kami.cloud.lang.JsonSerializer
import xyz.scootaloo.kami.cloud.lang.timestamp
import kotlin.reflect.KClass

/**
 * @author flutterdash@qq.com
 * @since 2022/4/10 15:05
 */
typealias SC = StatusCode

fun <T> messageOf(data: T? = null, status: SC = StatusCode.SUCCEED): HttpMessageResult<T> {
    return HttpMessageResult(status.succeeded, status.msg, status.code, data)
}

data class HttpMessageResult<T>(
    val success: Boolean,
    val message: String,
    val code: Int,
    val data: T?,
    val timestamp: String = timestamp()
)

/**
 * @param code 状态的唯一标识, 当[code]是偶数, 则代表操作成功, 奇数代表操作失败, 参考属性[succeeded]
 * @param msg  操作的描述;
 */
class StatusCode(val code: Int, val msg: String = "") : JsonSerializable {

    val succeeded: Boolean get() = code % 2 == 0

    companion object {
        /**
         * code 0~499: 基本状态
         */
        val SUCCEED = SC(0, "操作成功")
        val FAILURE = SC(1, "操作失败")

        /**
         * code 500~999: 系统内部状态
         */
        val SYSTEM_CACHE_INVALID = SC(501, "缓存失效")

        /**
         * code 1000~1999: http通信状态
         */
        val HTTP_SERVER_ERROR = SC(1001, "服务器内部错误")
        val HTTP_TOKEN_EXPIRED = SC(1101, "执行此操作所需的令牌已过期")
        val HTTP_INFO_INCOMPLETE = SC(1201, "提交的材料信息不完整")
        val HTTP_FORM_INCOMPLETE = SC(1203, "表单信息不完整")
        val HTTP_AUTH_FORMAT_INVALID = SC(1301, "身份验证信息格式错误")
        val HTTP_AUTH_ALG_NOT_SUPPORT = SC(1303, "身份验证算法不支持")
        val HTTP_AUTH_VERIFICATION_FAILED = SC(1305, "身份验证失败")

        /**
         * code 2000~2999: 文件系统状态
         */
        val FILE_NOT_FOUND = SC(2001, "文件未找到")
        val FILE_NOT_EXISTS = SC(2003, "文件不存在")
        val INSUFFICIENT_STORAGE_SPACE = SC(2005, "存储空间不足")
        val ACCESS_OUT_OF_BOUND = SC(2007, "访问超出限制")
        val NOT_DIRECTORY = SC(2009, "操作失败, 目标路径不是文件夹")
        val FILE_ALREADY_EXISTS = SC(2011, "文件已存在")

        /**
         * code 3000~3999: 权限状态
         */
        val NO_ACCESS_PERMISSION = SC(3001, "没有此文件夹的访问权限")
        val NO_DEFINE_PERMISSION = SC(3003, "没有此文件夹的定义权限")
        val NO_DOWNLOAD_PERMISSION = SC(3005, "没有此文件夹的下载权限")
        val NO_CREATION_PERMISSION = SC(3007, "没有此文件夹的修改权限")
        val NO_UPLOAD_PERMISSION = SC(3009, "没有此目录的上传权限")

        /**
         * code 4000~4999: 传输状态
         */
        val FILE_CHUNK_TRANSFER_SUCCESS = SC(4000, "文件块传输成功")
        val FILE_CHUNK_HAS_DUPLICATED_SUBMIT = SC(4002, "文件块已经提交过")
        val REQUEST_LACK_UPLOAD_FILE = SC(4101, "没有找到要上传的文件信息")
        val REQUEST_CARRYING_TOO_MANY_FILES = SC(4103, "请求携带的文件数量超过限制")
        val UPLOAD_TASK_NOT_EXISTS_OR_EXPIRY = SC(4201, "上传任务不存在或过期")
        val FILE_NOT_EXISTS_IN_TASK = SC(4203, "上传任务中不存在这个文件")

        /**
         * code 5000~5999: 账号状态
         */
        val ACCOUNT_REGISTER_SUCCESS = SC(5100, "注册用户成功")
        val ACCOUNT_LOGIN_SUCCESS = SC(5102, "登录成功")
        val USERNAME_DUPLICATE = SC(5103, "用户名'{}'已被注册")
        val ACCOUNT_USERNAME_NOT_EXISTS = SC(5105, "用户名'{}'不存在")
        val ACCOUNT_MATCHING_FAILURE = SC(5107, "账号或密码错误")

        /**
         * code 6000~ : 其他
         */
        val FEATURE_NOT_AVAILABLE = SC(6001, "功能暂未开放")
    }
}

object StatusCodeSerializer : JsonSerializer<StatusCode> {
    override fun accept(): KClass<StatusCode> {
        return StatusCode::class
    }

    override fun deserialize(json: JsonObject): StatusCode {
        return StatusCode(
            code = json.getInteger("code")!!,
            msg = json.getString("msg")!!
        )
    }
}